#include "sock.h"
#include <fstream>
#include <sys/stat.h>
#include <sys/types.h>

#define SIZE 1024 * 10
#define WWWROOT "./wwwroot/"
#define HOME_PAGE "index.html"

void Usage(char *args)
{
  std::cout << "Usage:\n\t" << args << " server.port" << std::endl;
}

void *service_run(void *args)
{
  int sock = *(int *)args;
  delete (int *)args;
  char buffer[SIZE] = {0};
  pthread_detach(pthread_self());

  ssize_t size = recv(sock, buffer, sizeof(buffer) - 1, 0);
  if (size > 0)
  {
    buffer[size] = 0;
    std::cout << buffer << std::endl;
    std::string response = "http/1.1 200 ok\n";
    std::string home_page = WWWROOT;
    home_page += HOME_PAGE;
    std::ifstream in(home_page);
    if (!in.is_open())
    {
      //std::cout << "home page open failed" << std::endl;
      std::cout << std::endl;
      std::cout << std::endl;
      std::cout << std::endl;
      std::cout << std::endl;
      std::string err_response = "http/1.1 404 NOT FOUND\n";
      err_response += "Content-Type: text/html; charset=utf8\n";
      err_response += "Content-Lenth: ";
      std::string err_info = "<html><p>the resourse you visited does not exist</p><html>";
      err_response += std::to_string(err_info.size());
      err_response += "\n\n";
      err_response += err_info;
      std::cout << err_response << std::cout << std::endl;
      std::cout << std::endl;
      std::cout << std::endl;
      std::cout << std::endl;
      send(sock, err_response.c_str(), err_response.size(), 0);
    }
    else
    {
      std::cout << "open success" << std::endl;
      std::string text_info;
      std::string line;
      while (std::getline(in, line)){
        text_info += line;
      }
      struct stat st;
      stat(home_page.c_str(), &st);
      response += "Content-Type: text/html; charset=utf8\n";
      response += "Content-Lenth: ";
      response += std::to_string(st.st_size);
      response += "\n\n";
      response += text_info;
      send(sock, response.c_str(), response.size(), 0);
      in.close();
    }
  }
  close(sock);
  return nullptr;
}

int main(int argc, char *argv[])
{
  if (argc != 2)
  {
    Usage(argv[1]);
    exit(1);
  }
  uint16_t ser_port = atoi(argv[1]);
  int sock = Sock::sock();
  Sock::Bind(sock, ser_port);
  Sock::Listen(sock);

  while (true)
  {
    int new_sock = Sock::Accept(sock);
    int *psock = new int(new_sock);
    pthread_t tid;
    pthread_create(&tid, nullptr, service_run, (void *)psock);
  }
}
